package com.iwomy.secureplat.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iwomy.secureplat.admin.api.entity.*;
import com.iwomy.secureplat.admin.api.vo.RoleExcelVO;
import com.iwomy.secureplat.admin.mapper.*;
import com.iwomy.secureplat.admin.service.SysMenuService;
import com.iwomy.secureplat.admin.service.SysRoleService;
import com.iwomy.secureplat.admin.service.SysTenantMenuService;
import com.iwomy.secureplat.admin.utils.RedisClient;
import com.iwomy.secureplat.common.data.tenant.TenantContextHolder;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 租户菜单管理
 */
@Service
@AllArgsConstructor
@Slf4j
public class SysTenantMenuServiceImpl extends ServiceImpl<SysTenantMenuMapper, SysTenantMenu>
		implements SysTenantMenuService {

	private final SysTenantMapper sysTenantMapper;
	private final SysMenuMapper sysMenuMapper;
	private final SysMenuService sysMenuService;

	private final SysRoleMenuMapper sysRoleMenuMapper;

	private final SysRoleService roleService;

	private final SysRoleMenuMapper roleMenuMapper;

	private final RedisClient redisClient;

	private final SysSetMealDetailMapper sysSetMealDetailMapper;


	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveTenant(SysTenantMenu sysTenantMenu) {
		boolean save = this.save(sysTenantMenu);
		String[] split = sysTenantMenu.getMenuIds().split(",");
		for (String id : split) {
			SysSetMealDetail sysSetMealDetail = new SysSetMealDetail();
			sysSetMealDetail.setMenuId(Long.valueOf(id));
			sysSetMealDetail.setSetMealId(sysTenantMenu.getId());
			sysSetMealDetailMapper.insert(sysSetMealDetail);
		}
		return save;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateTenant(SysTenantMenu newSysTenantMenu) {

		List<SysSetMealDetail> sysSetMealDetails = sysSetMealDetailMapper
				.selectList(Wrappers.<SysSetMealDetail>lambdaQuery()
						.eq(SysSetMealDetail::getSetMealId, newSysTenantMenu.getId()));


		boolean b = this.updateById(newSysTenantMenu);

		Long tenantId = TenantContextHolder.getTenantId();
		TenantContextHolder.clear();

		List<Long> oldMenuIdList = sysSetMealDetails.stream().map(SysSetMealDetail::getMenuId).collect(Collectors.toList());
		List<Long> newMenuIdList = Arrays.stream(newSysTenantMenu.getMenuIds().split(",")).map(x -> Long.valueOf(x)).collect(Collectors.toList());
		List<Long> tempList = BeanUtil.copyToList(oldMenuIdList, Long.class);
		//需要删除的
		oldMenuIdList.removeAll(newMenuIdList);
		List<Long> removedObjects = oldMenuIdList;
		if (ObjectUtil.isNotEmpty(removedObjects)) {
			LambdaQueryWrapper<SysSetMealDetail> deleteQW = Wrappers.<SysSetMealDetail>lambdaQuery()
					.eq(SysSetMealDetail::getSetMealId, newSysTenantMenu.getId())
					.in(SysSetMealDetail::getMenuId, removedObjects);
			sysSetMealDetailMapper.delete(deleteQW);
		}


		//需要新增的
		newMenuIdList.removeAll(tempList);
		List<Long> addedObjects = newMenuIdList;

		if (ObjectUtil.isNotEmpty(addedObjects)) {
			List<SysSetMealDetail> collect = addedObjects.stream().map(x -> {
				SysSetMealDetail sysSetMealDetail = new SysSetMealDetail();
				sysSetMealDetail.setSetMealId(newSysTenantMenu.getId());
				sysSetMealDetail.setMenuId(x);
				return sysSetMealDetail;
			}).collect(Collectors.toList());
			collect.stream().forEach(sysSetMealDetailMapper::insert);
		}


		//查询使用该套餐的租户,没有用户使用 则直接返回
		List<SysTenant> sysTenantList = sysTenantMapper.selectList(Wrappers.<SysTenant>lambdaQuery()
				.eq(SysTenant::getMenuId, newSysTenantMenu.getId()));
		TenantContextHolder.setTenantId(tenantId);
		if (ObjectUtil.isEmpty(sysTenantList)) return b;


		for (SysTenant sysTenant : sysTenantList) {
			TenantContextHolder.setTenantId(sysTenant.getId());
			//查询所有角色
			if (ObjectUtil.isNotEmpty(removedObjects)) {
				List<SysRole> list = roleService.list();
				//删除所有角色的菜单
				list.stream().forEach(x -> {
					roleMenuMapper.delete(Wrappers.<SysRoleMenu>lambdaQuery()
							.eq(SysRoleMenu::getRoleId, x.getRoleId()).in(SysRoleMenu::getMenuId, removedObjects));
				});
			}
			if (ObjectUtil.isNotEmpty(addedObjects)) {
				//给admin新增
				List<RoleExcelVO> roleExcelVOS = roleService.adminRole();
				roleExcelVOS.forEach(x -> {
					SysRoleMenu sysRoleMenu = new SysRoleMenu();
					sysRoleMenu.setRoleId(x.getRoleId());
					addedObjects.stream().forEach(y -> {
						sysRoleMenu.setMenuId(y);
						roleMenuMapper.insert(sysRoleMenu);
					});
				});
			}


			Set<String> strings = redisClient.listKeyByPrefix(sysTenant.getId().toString());
			strings.forEach(redisClient::del);
			TenantContextHolder.clear();
		}

		TenantContextHolder.setTenantId(tenantId);
		return b;
	}


	@Override
	public Long removeTenantMenu(Long id) {

		Long aLong = sysTenantMapper.selectCount(Wrappers.<SysTenant>lambdaQuery().eq(SysTenant::getMenuId, id));

		if (aLong < 1)
			this.removeById(id);

		return aLong;
	}

}
